# -*- coding: utf-8 -*-

#import webapp2
import models
import urllib
from time import sleep

from google.appengine.ext import ndb
from google.appengine.ext import blobstore
from google.appengine.api import urlfetch
from google.appengine.ext.webapp import blobstore_handlers
from handlers.base import AppHandler


class TestFormBlobstore(AppHandler):
    def get(self):
        form = """
            <form action="%s" id="post_add" method="post" enctype="multipart/form-data">
                <div class="form-image">
                <label for="img">Картинка:</label>
                <input id="img" class="form-control" type="file" name="file">
                </div>
                <input type="submit" value="Submit">
            </form>
        """ % blobstore.create_upload_url(self.url_for('upload-image-blobstore'))
        self.response.write(form)


# Blob strore images
class UploadImage(AppHandler):
    def post(self):
        picture = self.request.POST.get('upload')
        # post_list = [
        #     ('CKEditor', self.request.GET['CKEditor']),
        #     ('CKEditorFuncNum', self.request.GET['CKEditorFuncNum']),
        #     ('langCode', self.request.GET['langCode']),
        # ]
        post_list = []
        content_type, body = encode_multipart_formdata(
            post_list,
            [(picture.name.encode('utf-8'), picture.filename.encode('utf-8'), picture.value)],
            mimetype=picture.type
            )
        response = urlfetch.fetch(
            url=blobstore.create_upload_url(self.url_for('upload-image-blobstore')),
            payload=body,
            method=urlfetch.POST,
            headers={'Content-Type': content_type},
            deadline=30
            )

        # import pdb;pdb.set_trace()
        # self.redirect(upload_url)


class UploadImageBlobstore(blobstore_handlers.BlobstoreUploadHandler):
    def post(self):
        # Create photo
        print "Before load"
        upload = self.get_uploads('file')[0]
        # import pdb;pdb.set_trace()
        # upload = self.get_uploads('file')[0]
        print upload
        user_photo = models.Photo(image=str(upload.key))
        user_photo.put()
        print user_photo


class UserProfile(AppHandler):
    def post(self):
        picture = self.request.POST.get('picture')

        # Write new picture to blob
        content_type, body = BlobstoreUpload.encode_multipart_formdata(
          [], [('file', name, image)])
        response = urlfetch.fetch(
            url=blobstore.create_upload_url(self.uri_for('blobstore-upload')),
            payload=body,
            method=urlfetch.POST,
            headers={'Content-Type': content_type},
            deadline=30
        )
        blob_key = response.content


class Index(AppHandler):
    def get(self):
        posts = [{
            'title': x.title,
            'text': x.text,
            'date': x.date.strftime('%d/%m/%Y  %X'),
            'tags': x.tags,
            'post_url': self.url_for('show-post', post_id=x.key.id()),
        } for x in models.Post.query().order(-models.Post.date).fetch(20)]

        response_dict = {'posts': posts}
        self.response.write(self.render_str('index.html', response_dict))


# Post handlers
class ShowPosts(AppHandler):
    def get(self):
        posts = [{
            'title': x.title,
            'date': x.date.strftime('%d/%m/%Y  %X'),
            'post_url': self.url_for('show-post', post_id=x.key.id()),
            'edit_url': self.url_for('edit-post', post_id=x.key.id(), _full=True),
            'delete_url': self.url_for('delete-post', post_id=x.key.id()),
            'pictures': models.Photo.query(ancestor=x.key),
            } for x in models.Post.query().order(-models.Post.date).fetch(20)]
        response_dict = {'posts': posts}
        self.response.write(self.render_str('showPosts.html', response_dict))


class AddPost(AppHandler):
    """ Add post handler """
    def get(self):
        add_post_url = self.uri_for('add-post')
        render_dict = {'add_post_url': add_post_url}
        self.response.write(self.render_str('addpost.html', render_dict))

    def post(self):
        # Get form data from POST
        title = self.request.get('title')
        text = self.request.get('text')
        # Try in without unicode encoding
        tags = [x.strip() for x in self.request.get('tags').split(',')]
        # Create new post and save it.
        _post = models.Post(
            title=title,
            text=text,
            tags=tags,
        )
        _post.put()
        # Create tags
        for tag in tags:
            models.Tag.get_or_insert(tag)
        # return self.redirect("/admin/")

class ShowPost(AppHandler):
    """ Show post by id """
    def get(self, post_id):
        # Get post
        post = self.get_ndb_ent_by_id(models.Post, post_id)

        response_dict = {'post':post}
        self.response.write(self.render_str('showpost.html', response_dict))

class EditPost(AppHandler):
    """ Edit post by ID """
    def get(self, post_id):
        # Get post
        post = self.get_ndb_ent_by_id(models.Post, post_id)
        edit_post_url = self.url_for('edit-post', post_id=post.key.id())
        tags = ",".join(post.tags)
        response_dict = {"post":post, 'tags':tags, 'edit_post_url': edit_post_url}
        self.render_write('editpost.html', response_dict)

    def post(self, post_id):
        # Get post
        post = self.get_ndb_ent_by_id(models.Post, post_id)
        title = self.request.get('title')
        text = self.request.get('text')
        tags = [x.strip() for x in self.request.get('tags').split(',')]
        # Check if data was changed
        _put = False
        if post.title != title:
            post.title = title
            _put = True
        if post.text != text:
            post.text = text
            _put = True
        if post.tags != tags:
            post.tags = tags
            _put = True

        if _put:
            post.put()
            print 'Changed!'

        #return self.redirect('/admin/post/%s/' % post_id)

class DeletePost(AppHandler):
    """ Delete post by ID """
    def get(self, post_id):
        post = self.get_ndb_ent_by_id(models.Post, post_id)
        post.key.delete()
        return self.redirect('/admin/')

# Service handlers
class ServiceCategories(AppHandler):
    """ Show all services
        in template it forms list of tuples with category_name and category url
        event == add-category        : Add category
    """
    def get(self):
        # Get event parameter
        event = self.request.get('event')
        if not event:
            # Collect category_name an category url by parent key in list
            categories = [(x.name,urllib.quote(x.name.encode('utf-8'))) for x in models.ServiceCategory.query().fetch()]
            response_dict = {'categories':categories}
            self.render_write('showServices.html', response_dict)
        elif event == 'add-category':
            self.render_write('addServiceCategory.html')
        else:
            self.abort(404)

    def post(self):
        #Get event parameter
        event = self.request.get('event')
        if event == 'add-category':
            category_name = self.request.get('name')
            if category_name:
                # Check for double incoming of Category bu the same name
                if not models.ServiceCategory.query().filter(models.ServiceCategory.name==category_name).fetch():
                    models.ServiceCategory(name=category_name).put()
                    sleep(1)
            return self.redirect_to('categories')
        self.abort(404)

class ServiceCategoryTypes(AppHandler):
    """ Show category type entities by category key parent
        event == delete-category     : Delete Category
        event == edit-category       : Edit category
        event == add-type        : Add type
    """
    def get(self,category_url):
        """ Form tuple (type_name, type_description, type_url)
        """
        category_name = urllib.unquote(category_url)
        # Get service category key
        category = self.get_ndb_ent_by_name(models.ServiceCategory, category_name)
        category_key = category.key
        # Get event parameter
        event = self.request.get('event')
        if not event:
            # Show category Types
            #print category_key
            # Get category type entities with category key parent
            types = [(x.name, x.description, self.uri_for('category-type',category_url=category_url,type_url=x.name))
                     for x in models.ServiceType.query(ancestor=category_key).fetch()]
            render_dict = {'types':types}
            self.render_write('serviceCategoryTypes.html', render_dict)
        elif event == 'edit-category':
            render_dict = {'category_name':category.name}
            self.render_write('editServiceCategory.html', render_dict)
        elif event == 'delete-category':
            category_key.delete()
            self.redirect_to('categories')
        elif event == 'add-type':
            self.render_write('addServiceType.html')

    def post(self, category_url):
        category_name = urllib.unquote(category_url)
        # Get service category key
        category = self.get_ndb_ent_by_name(models.ServiceCategory, category_name)
        category_key = category.key
        event = self.request.get('event')
        if event == 'edit-category':
            category_name_get = self.request.get('name')
            if category_name != category_name_get:
                category.name = category_name_get
                if self.check_ndb_ent(models.ServiceCategory, category_name_get):
                    category_url = category_name_get.encode('utf-8')
                    category.put()
                sleep(1)
        elif event == 'add-type':
            # Get data from form
            name = self.request.get('name')
            description = self.request.get('text')
            # Create new type entity
            if name and description:
                # Check for double incoming of Type with the same name and parent
                if not models.ServiceType.query(ancestor=category_key).filter(models.ServiceCategory.name==name).fetch():
                    type = models.ServiceType(name=name, description=description, parent=category_key)
                    type.put()
                    sleep(1)
        self.redirect_to('category-types', category_url=category_url)

class ShowServiceType(AppHandler):
    """ Work with service entities through get parameter "event"
        event == delete-type     : Delete type
        event == edit-type       : Edit type
    """
    def get(self, category_url, type_url):
        category_name = urllib.unquote(category_url)
        type_name = urllib.unquote(type_url)
        parent_key = self.get_ndb_ent_by_name(models.ServiceCategory, category_name).key
        type = self.get_ndb_ent_by_name(models.ServiceType, type_name, ancestor=parent_key)
        render_dict = {'type':type}
        # Get event parameter
        event = self.request.get('event')
        if not event:
            self.render_write('showServiceType.html', render_dict)
        elif event == 'edit-type':
            self.render_write('editServiceType.html', render_dict)
        elif event == 'delete-type':
            type.key.delete()
            self.redirect_to('category-types', category_url=category_url)
        else:
            self.abort(404)

    def post(self, category_url, type_url):
        category_name = urllib.unquote(category_url)
        type_name = urllib.unquote(type_url)
        parent_key = self.get_ndb_ent_by_name(models.ServiceCategory, category_name).key
        type = self.get_ndb_ent_by_name(models.ServiceType, type_name, ancestor=parent_key)
        # Get event parameter
        event = self.request.get('event')
        if event == 'edit-type':
            # Create new entity if name was changed
            type_name_get = self.request.get('name')
            description = self.request.get('text')
            if (type_name != type_name_get) or (description != type.description):
                type.name = type_name_get
                type.description = description
                if self.check_ndb_ent(models.ServiceType, type_name_get, ancestor=parent_key):
                    type.put()
                    type_url = type_name_get.encode('utf-8')
                sleep(1)
        self.redirect_to('category-type', category_url=category_url, type_url=type_url)


def encode_multipart_formdata(fields, files, mimetype='image/png'):
    """
    Args:
      fields: A sequence of (name, value) elements for regular form fields.
      files: A sequence of (name, filename, value) elements for data to be
        uploaded as files.

    Returns:
      A sequence of (content_type, body) ready for urlfetch.
    """
    boundary = 'paLp12Buasdasd40tcxAp97curasdaSt40bqweastfarcUNIQUE_STRING'
    crlf = '\r\n'
    line = []
    for (key, value) in fields:
        line.append('--' + boundary)
        line.append('Content-Disposition: form-data; name="%s"' % key)
        line.append('')
        line.append(value)
    for (key, filename, value) in files:
        line.append('--' + boundary)
        line.append('Content-Disposition: form-data; name="%s"; filename="%s"' % (key, filename))
        line.append('Content-Type: %s' % mimetype)
        line.append('')
        line.append(value)
    line.append('--%s--' % boundary)
    line.append('')
    body = crlf.join(line)
    content_type = 'multipart/form-data; boundary=%s' % boundary
    return content_type, body
